package cn.infrabase.core.io;

import cn.infrabase.core.io.file.FileNotExistException;

import javax.annotation.Nullable;
import java.io.*;

/**
 * 输入输出工具类。
 *
 * @author Weimin Gao
 * @since 1.0.0
 **/
public class IoUtils {

    /**
     * 默认缓存大小8192
     */
    public static final int DEFAULT_BUFFER_SIZE = 8192;

    /**
     * 返回给定文件的输入流。
     *
     * @param file 给定的文件。
     * @return 文件输入流。
     * @throws FileNotExistException 如果给定的文件不存在时。
     */
    public static FileInputStream toStream(File file) throws FileNotExistException {
        try {
            return new FileInputStream(file);
        } catch (FileNotFoundException e) {
            throw new FileNotExistException(file);
        }
    }

    /**
     * 关闭（失败不会抛出异常）
     *
     * @param closeable 被关闭的对象。
     */
    public static void close(@Nullable Closeable closeable) {
        if (null != closeable) {
            try {
                closeable.close();
            } catch (Exception e) {
                // 忽略
            }
        }
    }

    /**
     * 将给定的输出流转换为缓冲输出流。
     *
     * @param os 给定的输出流。
     * @return 缓冲输出流。
     */
    public static BufferedOutputStream toBuffered(OutputStream os) {
        return (os instanceof BufferedOutputStream) ? (BufferedOutputStream) os : new BufferedOutputStream(os);
    }

    /**
     * 将给定的输入流转换为缓冲输入流。
     *
     * @param is 给定的输入流。
     * @return 缓冲输入流。
     */
    public static BufferedInputStream toBuffered(InputStream is) {
        return (is instanceof BufferedInputStream) ? (BufferedInputStream) is : new BufferedInputStream(is);
    }

//    // -----------------------------------------------------------------------------------------------------------------
//    // copy
//
//    /**
//     * 复制输入流中数据至输出流中，返回复制数据的长度（字节），拷贝后不关闭流。
//     *
//     * @param in       输入流。
//     * @param out      输出流。
//     * @param buffer   复制缓存大小（字节）。
//     * @param count    需要复制数据的长度（字节）。
//     * @param progress 复制进度条。
//     * @return 复制数据的长度（字节）。
//     */
//    public static long copy(InputStream in, OutputStream out, int buffer, long count, StreamProgress progress) {
//        return new StreamCopier(buffer, count, progress).copy(in, out);
//    }
//
//    /**
//     * 复制输入流中数据至输出流中，返回复制数据的长度（字节），拷贝后不关闭流。
//     *
//     * @param in       输入流。
//     * @param out      输出流。
//     * @param buffer   复制缓存大小（字节）。
//     * @param progress 复制进度条。
//     * @return 复制数据的长度（字节）。
//     */
//    public static long copy(InputStream in, OutputStream out, int buffer, StreamProgress progress) {
//        return copy(in, out, buffer, -1, progress);
//    }
//
//    /**
//     * 复制输入流中数据至输出流中，返回复制数据的长度（字节），拷贝后不关闭流。
//     *
//     * @param in     输入流。
//     * @param out    输出流。
//     * @param buffer 复制缓存大小（字节）。
//     * @return 复制数据的长度（字节）。
//     */
//    public static long copy(InputStream in, OutputStream out, int buffer) {
//        return copy(in, out, buffer, null);
//    }
//
//    /**
//     * 复制输入流中数据至输出流中，返回复制数据的长度（字节），拷贝后不关闭流。
//     *
//     * @param in  输入流。
//     * @param out 输出流。
//     * @return 复制数据的长度（字节）。
//     */
//    public static long copy(InputStream in, OutputStream out) {
//        return copy(in, out, DEFAULT_BUFFER_SIZE);
//    }

    // -----------------------------------------------------------------------------------------------------------------
    // readBytes

//    /**
//     * 从流中读取内容，读到输出流中，读取完毕后可选是否关闭流。
//     *
//     * @param in      输入流。
//     * @param isClose 读取完毕后是否关闭流。
//     * @return 输出流。
//     */
//    public static FastByteArrayOutputStream read(InputStream in, boolean isClose) {
//        final FastByteArrayOutputStream out;
//        if (in instanceof FileInputStream) {
//            // 文件流的长度是可预见的，此时直接读取效率更高
//            try {
//                out = new FastByteArrayOutputStream(in.available());
//            } catch (IOException e) {
//                throw new IoRuntimeException(e);
//            }
//        } else {
//            out = new FastByteArrayOutputStream();
//        }
//        try {
//            copy(in, out);
//        } finally {
//            if (isClose) {
//                close(in);
//            }
//        }
//        return out;
//    }

//    /**
//     * 从输入流中读取数据。
//     *
//     * @param in      输入流。
//     * @param isClose 读取完成是否关闭输入流。
//     * @return 读取的数据。
//     */
//    public static byte[] readBytes(InputStream in, boolean isClose) {
//        if (in instanceof FileInputStream) {
//            // 文件流的长度是可预见的，此时直接读取效率更高
//            final byte[] result;
//            try {
//                final int available = in.available();
//                result = new byte[available];
//                final int readed = in.read(result);
//                if (readed != available) {
//                    throw new IOException(StringUtils.format("文件长度为[{}]但读取为[{}]", available, readed));
//                }
//            } catch (IOException e) {
//                throw new IoRuntimeException(e);
//            } finally {
//                if (isClose) {
//                    close(in);
//                }
//            }
//            return result;
//        }
//        // 未知bytes总量的流
//        return read(in, isClose).toByteArray();
//    }

//    /**
//     * 从流中读取数据返回字节数组，读取完毕后关闭流。
//     *
//     * @param in 输入流。
//     * @return 字节数组。
//     */
//    public static byte[] readBytes(InputStream in) {
//        return readBytes(in, true);
//    }

}

